

#include "EventLoopThreadPool.hpp"
#include "EventLoop.hpp"
#include "EventLoopThread.hpp"

namespace zephyr {

EventLoopThreadPool::EventLoopThreadPool(EventLoop *base_loop, const std::string &name)
    : base_loop(base_loop)
    , m_name(name)
    , m_started(false)
    , m_numThread(0)
    , m_next(0) {

}

EventLoopThreadPool::~EventLoopThreadPool() {
    // Don't delete loop, it's stack variable
}

void EventLoopThreadPool::start(const ThreadInitCallback &cb) {
    m_started = true;
    for (int i = 0; i < m_numThread; i++) {
        char buf[m_name.size() + 32];
        snprintf(buf, sizeof(buf), "%s%d", m_name.c_str(), i);
        EventLoopThread *t = new EventLoopThread(cb, buf);
        m_threads.push_back(std::unique_ptr<EventLoopThread>(t));
        m_loops.push_back(t->startLoop());
    }

    if (m_numThread == 0 && cb) {
        cb(base_loop);
    }
}

EventLoop *EventLoopThreadPool::getNextLoop() {
    EventLoop *loop = base_loop;
    if (!m_loops.empty()) {
        loop = m_loops[m_next];
        m_next ++;
        if (m_next >= m_loops.size()) {
            m_next = 0;
        }
    }
    return loop;
}

std::vector<EventLoop *> EventLoopThreadPool::getAllLoop() {
    if (m_loops.empty()) {
        return std::vector<EventLoop *>(1, base_loop);
    } else {
        return m_loops;
    }
}

}